/*
 * minet_hal.c
 *
 *  Created on: 2019年4月27日
 *      Author: 0yfj0
 */

#include "minet.h"

/*----------------------------------------------------------------------------*/
#if (MINET_RFSOC==MINET_RFSOC_TODO)
void minet_hal_wdt_feed(void)
{
	/* TODO: */
}
uint32_t minet_hal_tick1s(void)
{
	/* TODO: */
	return 0;
}

uint32_t minet_hal_random(void)
{
	/* TODO: */
	return minet_hal_tick1s();
}

int minet_hal_init(minet_if_t *nif)
{
	/* TODO: */
	return -1;
}
int minet_hal_rssi(minet_if_t *nif)
{
	/* TODO: */
	return 0;
}
int minet_hal_chl(minet_if_t *nif, int chl)
{
	nif->chl = chl % MINET_CHL_MAX;
	/* TODO: */
	return 0;
}
int minet_hal_cd(minet_if_t *nif)
{
	/* TODO:除CD功能，添加<100ms空中数据延时 */
	return 0;
}
int minet_hal_write(minet_if_t *nif, void *buf, int len)
{
	/* TODO: */
	return 0;
}
int minet_hal_read(minet_if_t *nif, void *buf, int sz)
{
	/* TODO: */
	return 0;
}
#elif (MINET_RFSOC==MINET_RFSOC_QTSIM)
#include <string.h>
#include <time.h>
#include <stdio.h>
#define MINET_CHL_MAX 16
typedef struct simdev_fifo
{
	uint16_t addr;
	uint8_t buf[MINET_FLEN_MAX];
	uint16_t len;
	struct simdev_fifo *next;
}simdev_fifo_t;
typedef struct
{
	int x[MINET_NODEMAX];
	int y[MINET_NODEMAX];
	minet_if_t *nif[MINET_NODEMAX];
	simdev_fifo_t *rxfifo[MINET_NODEMAX];
}simdev_t;
simdev_t simdev;
int simlock = 0;

void minet_hal_debug(minet_if_t *nif, uint8_t *buf, int len, int method);
void minet_simdev_init(void);
void minet_hal_fifo_push(simdev_fifo_t **head, simdev_fifo_t *fifo);
simdev_fifo_t *minet_hal_fifo_pop(simdev_fifo_t **head);

void minet_hal_wdt_feed(void)
{
}
uint32_t minet_hal_tick1s(void)
{
	return (uint32_t) time(NULL);
}

uint32_t minet_hal_random(void)
{
	return minet_hal_tick1s();
}

int minet_hal_init(minet_if_t *nif)
{
	int idx = nif->addr;
	simdev.nif[idx] = nif;
	return 0;
}
int minet_hal_rssi(minet_if_t *nif)
{
	return 31;
}
int minet_hal_chl(minet_if_t *nif, int chl)
{
	nif->chl = chl % MINET_CHL_MAX;
	return 0;
}
int minet_hal_cd(minet_if_t *nif)
{
	/* TODO:除CD功能，添加10ms空中数据延时 */
	return 0;
}
int minet_hal_write(minet_if_t *nif, void *buf, int len)
{
	int x, y, x1, y1, idx;
	simdev_fifo_t *fifo;

	idx = nif->addr;
	x = simdev.x[idx];
	y = simdev.y[idx];
	minet_hal_debug(nif, buf, len, 1);
	for (int i = 0; i < MINET_NODEMAX; ++i)
	{
		if (simdev.nif[i] != NULL && simdev.nif[i] != nif)
		{
			x1 = simdev.x[i] - x;
			y1 = simdev.y[i] - y;
			if (sqrt(x1 * x1 + y1 * y1) < 130)
			{
				while (simlock != 0)
				{
				}
				simlock = 1;

				fifo = (simdev_fifo_t*) malloc(sizeof(simdev_fifo_t));
				fifo->addr = nif->addr;
				memcpy(fifo->buf, buf, len);
				fifo->len = len;
//                minet_hal_debug(nif, buf, len, 1);
				minet_hal_fifo_push(&simdev.rxfifo[i], fifo);
//                printf("write to %d\n", i);fflush(stdout);

				simlock = 0;
			}
		}
	}
	return len;
}
int minet_hal_read(minet_if_t *nif, void *buf, int sz)
{
	int idx;
	simdev_fifo_t *fifo;

	idx = nif->addr;
	fifo = minet_hal_fifo_pop(&simdev.rxfifo[idx]);
	if (fifo != NULL)
	{
		if (fifo->len < sz)
		sz = fifo->len;
		memcpy(buf, fifo->buf, sz);
		minet_hal_debug(nif, buf, sz, 0);
		free(fifo);
		return sz;
	}
	return 0;
}

void minet_simdev_init(void)
{
	simdev_fifo_t *fifo;

	simlock = 0;
	for (int i = 0; i < MINET_NODEMAX; ++i)
	{
		simdev.nif[i] = NULL;
		for (fifo = simdev.rxfifo[i]; fifo != NULL; fifo = fifo->next)
		free(fifo);
		simdev.rxfifo[i] = NULL;
	}
}

void minet_hal_fifo_push(simdev_fifo_t **head, simdev_fifo_t *fifo)
{
	simdev_fifo_t *curr = *head;

	if (curr != NULL)
	{
		while (curr->next != NULL)
		curr = curr->next;
		curr->next = fifo;
		fifo->next = NULL;
	}
	else
	{
		*head = fifo;
		fifo->next = NULL;
	}
}

simdev_fifo_t *minet_hal_fifo_pop(simdev_fifo_t **head)
{
	simdev_fifo_t *fifo = *head;

	if (*head != NULL)
	*head = (*head)->next;
	return fifo;
}

extern int minet_msg_legal(minet_if_t *nif, uint8_t *buf, int len);
#define minet_parse_flen(ptr) (((uint8_t*)ptr)[0])
#define minet_parse_seq(ptr) (((uint8_t*)ptr)[1])
#define minet_parse_ctrl(ptr) (((uint8_t*)ptr)[2])
#define minet_parse_ctrl_rlhops(ptr) (minet_parse_ctrl(ptr)&7)
#define minet_parse_ctrl_ftyp(ptr) ((minet_parse_ctrl(ptr)>>3)&7)
#define minet_parse_ctrl_relay(ptr) ((minet_parse_ctrl(ptr)>>6)&1)
#define minet_parse_paddr(ptr) (&((uint8_t*)ptr)[3])
#define minet_parse_payload(ptr,rlhops) (&((uint8_t*)ptr)[MINET_FLEN_MIN-2+2*(rlhops)])
#define minet_parse_dlen(flen,rlhops) ((flen)-(MINET_FLEN_MIN+2*(rlhops)))
void minet_hal_debug(minet_if_t *nif, uint8_t *buf, int len, int method)
{
	time_t now = time(NULL);
	struct tm *tm = localtime(&now);
	printf("%d-%02d-%02dT%02d:%02d:%02d %s%04X", tm->tm_year + 1900,
			tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
			method ? "W" : "R", nif->addr);
	if (minet_msg_legal(nif, buf, len) == 0)
	{
		uint8_t rlhops = minet_parse_ctrl_rlhops(buf);
		uint8_t ftyp = minet_parse_ctrl_ftyp(buf);
		uint8_t *paddr = minet_parse_paddr(buf);
		uint16_t dest = ((uint16_t) paddr[0] << 8) | paddr[1];
		uint16_t src = ((uint16_t) paddr[2 + 2 * rlhops] << 8)
		| paddr[3 + 2 * rlhops];

		printf("\033[%dm", 30 + src);
		printf(" [%04X", dest);
		for (int i = 1; i <= rlhops; ++i)
		{
			uint16_t addr = ((uint16_t) paddr[2 * i] << 8) | paddr[2 * i + 1];
			printf(",%04X", addr);
		}
		printf(",%04X]", src);
		if (ftyp == MINET_FTYP_ANN)
		printf(" [announce]");
		else if (ftyp == MINET_FTYP_PING)
		printf(" [ping]");
		else if (ftyp == MINET_FTYP_DATA)
		printf(" [data]");
		else if (ftyp == MINET_FTYP_ACK)
		printf(" [acknowledge]");
		else
		printf(" [unknow]");
	}
	else
	{
		printf(" \033[41m\033[37m[legal]");
	}

	printf(" [");
	for (int i = 0; i < len; ++i)
	printf("%02X ", buf[i]);
	printf("]\n");
	printf("\033[0m");
	fflush(stdout);
}

#elif (MINET_RFSOC==MINET_RFSOC_CC2530)
#include <string.h>
#include "sys.h"
#include "ti_rf.h"
#include "ieee802154.h"
#include "minet.h"

void minet_hal_wdt_feed(void)
{
	sys_watchdog_feed();
}
uint32_t minet_hal_tick1s(void)
{
	return sys.run;
}
uint32_t minet_hal_random(void)
{
	uint32_t r = sys.tick & 0xFFF;
	return sys.run ^ r;
}
extern void ieee802154_hal_init(uint16_t addr, uint8_t chl);
int minet_hal_init(minet_if_t *nif)
{
	ieee802154_hal_init(nif->addr, nif->chl);
	return 0;
}
int minet_hal_rssi(minet_if_t *nif)
{
	return rf_rssi_get();
}
int minet_hal_chl(minet_if_t *nif, int chl)
{
	uint16_t panid;

	nif->chl = chl % MINET_CHL_MAX;
	ieee802154.channel = (nif->chl & 0x0F) + 11;
	panid = (uint16_t) (nif->nid + ieee802154.channel);
	rf_panid_set(panid);
	return rf_channel_set(ieee802154.channel);
}
int minet_hal_cd(minet_if_t *nif)
{
	if (rf_pending_packet() == 1)/* TODO:cc2530检测数据接收暂时有点问题 */
	{
		uint32_t r = minet_hal_random() % 10;
		sys_delay(r);/* 除CD功能，添加<100ms空中数据延时 */

		r = minet_hal_random() % 10;
		sys_delay(r);
		return 0;
	}
	return 0;
}
#define minet_parse_ctrl(ptr) (((uint8_t*)ptr)[2])
#define minet_parse_ctrl_relay(ptr) ((minet_parse_ctrl(ptr)>>6)&1)
int minet_hal_write(minet_if_t *nif, void *buf, int len)
{
	static ieee802154_mpdu_info_t info;
	static ieee802154_data_frame_info_t frame_info;

	int8_t err;
	uint16_t panid;

	if (len < MINET_FLEN_MIN)
		return 0;

	/* flen(1byte)|seq(1byte)|ctrl(1byte)|dest(2byte) source(2byte) ...|[payload(n byte)]|sign(1byte)|crc8(1byte) */
	panid = (uint16_t) (nif->nid + ieee802154.channel);
//	if (minet_parse_ctrl_relay(buf) != 0)
//	{
//		frame_info.dest_addr[1] = 0xFF;
//		frame_info.dest_addr[0] = 0xFF;
//	}
//	else
	{
		frame_info.dest_addr[1] = ((uint8_t*) buf)[3];
		frame_info.dest_addr[0] = ((uint8_t*) buf)[4];
	}
	frame_info.dest_addr_mode = IEEE802154_ADDR_MODE_16BIT;
	frame_info.dest_panid = panid;

	frame_info.src_addr[0] = (uint8_t) (nif->addr >> 0);
	frame_info.src_addr[1] = (uint8_t) (nif->addr >> 8);
	frame_info.src_addr_mode = IEEE802154_ADDR_MODE_16BIT;
	frame_info.src_panid = panid;
	frame_info.payload_len = (uint8_t) len;
	ieee802154_data_frame_build_info(&info, &frame_info, buf);
	/*
	 * RF_TX_OK - success
	 * RF_TX_ERR - transmit error
	 * RF_TX_COLLISION - collision error
	 * RF_TX_NOACK - transmit success but not ack
	 *  */
	err = ieee802154_write(&info);
	if (err == RF_TX_OK)
		return len;
	return 0;
}
int minet_hal_read(minet_if_t *nif, void *buf, int sz)
{
	ieee802154_rxinfo_t *rxinfo;

	rxinfo = ieee802154_read(buf, (uint8_t) sz);
	if (rxinfo != NULL)
		return rxinfo->frame.payload_len;
	return 0;
}

#elif (MINET_RFSOC==MINET_RFSOC_BK2425)
#include <string.h>
#include <drv_spi.h>
#include <sys.h>
void minet_hal_wdt_feed(void)
{
	sys_watchdog_feed();
}
uint32_t minet_hal_tick1s(void)
{
	return sys.run;
}
uint32_t minet_hal_random(void)
{
	uint32_t r = sys.tick & 0xFFF;
	return sys.run ^ r;
}

/*----------------------------------------------------------------------------*/
// SPI(BK2425) commands
#define CMD_RD_REG		( 0x00 )// Define read command to register
#define CMD_WR_REG		( 0x20 )// Define write command to register
#define CMD_RD_RXPLOAD	( 0x61 )// Define RX payload register address
#define CMD_WR_TXPLOAD	( 0xA0 )// Define TX payload register address
#define CMD_WR_TXPLOAD_NOACK	( 0xB0 )// Define TX payload register addres
#define CMD_FLUSH_TX	( 0xE1 )// Define flush TX register command
#define CMD_FLUSH_RX	( 0xE2 )// Define flush RX register command
#define CMD_REUSE_TX_PL	( 0xE3 )// Define reuse TX payload register command
#define CMD_NOP			( 0xFF )// Define No Operation, might be used to read status register

// SPI(BK2425) registers(addresses)
#define REG_CONFIG		( 0x00 )// 'Config' register address
#define REG_EN_AA		( 0x01 )// 'Enable Auto Acknowledgment' register address
#define REG_EN_RXADDR	( 0x02 )// 'Enabled RX addresses' register address
#define REG_SETUP_AW	( 0x03 )// 'Setup address width' register address
#define REG_SETUP_RETR	( 0x04 )// 'Setup Auto. Retrans' register address
#define REG_RF_CH		( 0x05 )// 'RF channel' register address
#define REG_RF_SETUP	( 0x06 )// 'RF setup' register address
#define REG_STATUS		( 0x07 )// 'Status' register address
#define REG_OBSERVE_TX	( 0x08 )// 'Observe TX' register address
#define REG_CD			( 0x09 )// 'Carrier Detect' register address
#define REG_RX_ADDR_P0	( 0x0A )// 'RX address pipe0' register address
#define REG_RX_ADDR_P1	( 0x0B )// 'RX address pipe1' register address
#define REG_RX_ADDR_P2	( 0x0C )// 'RX address pipe2' register address
#define REG_RX_ADDR_P3	( 0x0D )// 'RX address pipe3' register address
#define REG_RX_ADDR_P4	( 0x0E )// 'RX address pipe4' register address
#define REG_RX_ADDR_P5	( 0x0F )// 'RX address pipe5' register address
#define REG_TX_ADDR		( 0x10 )// 'TX address' register address
#define REG_RX_PW_P0	( 0x11 )// 'RX payload width, pipe0' register address
#define REG_RX_PW_P1	( 0x12 )// 'RX payload width, pipe1' register address
#define REG_RX_PW_P2	( 0x13 )// 'RX payload width, pipe2' register address
#define REG_RX_PW_P3	( 0x14 )// 'RX payload width, pipe3' register address
#define REG_RX_PW_P4	( 0x15 )// 'RX payload width, pipe4' register address
#define REG_RX_PW_P5	( 0x16 )// 'RX payload width, pipe5' register address
#define REG_FIFO_STATUS		( 0x17 )// 'FIFO Status Register' register address

// REG_STATUS Register
#define RX_DR			( 0x40 )/*  */
#define TX_DS			( 0x20 )
#define MAX_RT			( 0x10 )

/*----------------------------------------------------------------------------*/
#define BK2425_ADDR_SZ	( 5 ) // 发送/接收地址
#define BK2425_PLOAD_SZ ( 32 )// 数据通道有效数据宽度

#include <stm32f4xx_ll_gpio.h>
#include <main.h>
//BK2425 PIN DEFINITION
void bk2425_cs_clr(int n)
{
	if (n == 0)
	LL_GPIO_ResetOutputPin(SPI1_CS_GPIO_Port, SPI1_CS_Pin);/* SPI Chip Select, Active low */
	else if (n == 1)
	LL_GPIO_ResetOutputPin(SPI2_CS_GPIO_Port, SPI2_CS_Pin);
}
void bk2425_cs_set(int n)
{
	if (n == 0)
	LL_GPIO_SetOutputPin(SPI1_CS_GPIO_Port, SPI1_CS_Pin);/* SPI Chip Select, Active low */
	else if (n == 1)
	LL_GPIO_SetOutputPin(SPI2_CS_GPIO_Port, SPI2_CS_Pin);
}
void bk2425_ce_clr(int n)
{
	if (n == 0)
	LL_GPIO_ResetOutputPin(SPI1_CE_GPIO_Port, SPI1_CE_Pin);/* Chip Enable Activates RX or TX mode */
	else
	LL_GPIO_ResetOutputPin(SPI2_CE_GPIO_Port, SPI2_CE_Pin);
}
void bk2425_ce_set(int n)
{
	if (n == 0)
	LL_GPIO_SetOutputPin(SPI1_CE_GPIO_Port, SPI1_CE_Pin);/* Chip Enable Activates RX or TX mode */
	else
	LL_GPIO_SetOutputPin(SPI1_CE_GPIO_Port, SPI1_CE_Pin);
}
//#define bk2425_irq(n) ( 0 )// Interrupt signal
int bk2425_irq(int n)// Interrupt signal
{
	int v = 0;

	if (n == 1)
	v = (LL_GPIO_ReadInputPort(SPI1_IRQ_GPIO_Port) & SPI1_IRQ_Pin) ? 1 : 0;
	else
	v = (LL_GPIO_ReadInputPort(SPI2_IRQ_GPIO_Port) & SPI2_IRQ_Pin) ? 1 : 0;

	return v;
}

static int bk2425_reg_write(int n, uint8_t reg, uint8_t val)
{
	uint8_t buf[2] =
	{	reg, val};

	bk2425_cs_clr(n);
	spi_write(n, buf, 2);
	bk2425_cs_set(n);
	return 1;
}
static int bk2425_buf_write(int n, uint8_t reg, uint8_t *buf, int bytes)
{
	bk2425_cs_clr(n);
	spi_write(n, &reg, 1);
	spi_write(n, buf, bytes);
	bk2425_cs_set(n);
	return bytes;
}
static uint8_t bk2425_reg_read(int n, uint8_t reg)
{
	uint8_t value;

	bk2425_cs_clr(n);
	spi_write(n, &reg, 1);
	spi_read(n, &value, 1);
	bk2425_cs_set(n);
	return value;
}
static int bk2425_buf_read(int n, uint8_t reg, uint8_t *buf, int bytes)
{
	bk2425_cs_clr(n);
	memset(buf, 0xFF, bytes);
	spi_write(n, &reg, 1);
	spi_read(n, buf, bytes);
	bk2425_cs_set(n);
	return bytes;
}
static int bk2425_addr(int n, int a)
{
	uint8_t addr[BK2425_ADDR_SZ + 1];

	a += 11111;
	snprintf((char*) addr, sizeof(addr), "%d", a);
	bk2425_buf_write(n, CMD_WR_REG + REG_RX_ADDR_P0, addr, BK2425_ADDR_SZ);/* 接收设备接收通道0地址 */
	snprintf((char*) addr, sizeof(addr), "%d", a);
	bk2425_buf_write(n, CMD_WR_REG + REG_TX_ADDR, addr, BK2425_ADDR_SZ);/* 发送地址 */
	return 0;
}

/*----------------------------------------------------------------------------*/
/* BANK0 寄存器描述
 * CONFIG - 中断MASK, CRC, PWR_UP, PRIM_RX 默认中断全部使能/开启CRC8/PWR_UP=0/PRIM_RX=0
 * EN_AA - Enable ‘Auto Acknowledgment’ Function 默认AUTOACK全部开启
 * EN_RXADDR - Enabled RX Addresses 默认只使能0/1pipe
 * SETUP_AW - Setup of Address Widths(common for all data pipes) 默认5byte地址长度
 * SETUP_RETR - Setup of Automatic Retransmission 默认自动重发250us/最多3次重发
 * RF_CH - RF Channel 默认2.4GH+2MHz
 * RF_SETUP - RF Setup Register 默认空中速率2Mbps
 * STATUS - STATUS
 * OBSERVE_TX - Transmit observe register
 * CD - Carrier Detect
 * RX_ADDR_P0 - 0xE7E7E7E7E7
 * TX_ADDR - 0xE7E7E7E7E7
 * FIFO_STATUS - FIFO Status Register
 * DYNPD - Enable dynamic payload length 默认固定长度32byte */
int minet_hal_init(minet_if_t *nif)
{
	int n;

	n = nif->nbus;
	if (n == 0)
	{
		spi_init(n);
		LL_GPIO_SetOutputPin(SPI1_CS_GPIO_Port, SPI1_CS_Pin);
		LL_GPIO_ResetOutputPin(SPI1_CE_GPIO_Port, SPI1_CE_Pin);
	}
	else if (n == 1)
	{
		spi_init(n);
		LL_GPIO_SetOutputPin(SPI2_CS_GPIO_Port, SPI2_CS_Pin);
		LL_GPIO_ResetOutputPin(SPI2_CE_GPIO_Port, SPI2_CE_Pin);
	}
	bk2425_addr(n, nif->nid);
	if (n == 0)
	LL_GPIO_SetOutputPin(SPI1_CE_GPIO_Port, SPI1_CE_Pin);
	else if (n == 1)
	LL_GPIO_SetOutputPin(SPI2_CE_GPIO_Port, SPI2_CE_Pin);

	bk2425_reg_write(n, CMD_WR_REG + REG_EN_AA, 0x01);/* Disable ‘Auto Acknowledgment’ Function */
	bk2425_reg_write(n, CMD_WR_REG + REG_EN_RXADDR, 0x01);/* Enabled RX Addresses */
	bk2425_reg_write(n, CMD_WR_REG + REG_CONFIG, 0x0F);/* EN_CRC=1/2byte,PWR_UP=1,PRIM_RX=1 */
	bk2425_reg_write(n, CMD_WR_REG + REG_STATUS, 0xFF); /* 清除所有的中断标志位 */
	return 0;
}
int minet_hal_rssi(minet_if_t *nif)
{
	/* TODO: */
	return -60;
}
int minet_hal_chl(minet_if_t *nif, int chl)
{
	if (nif == NULL)
	return -1;

	nif->chl = chl % MINET_CHL_MAX;
	bk2425_reg_write(nif->nbus, CMD_WR_REG + REG_RF_CH, nif->chl);/* 射频通道 */
	bk2425_addr(nif->nbus, nif->nid + nif->chl);
	return 0;
}
int minet_hal_cd(minet_if_t *nif)
{
	uint8_t cd;

	cd = bk2425_reg_read(nif->nbus, CMD_RD_REG + REG_CD);
	/* TODO:除CD功能，添加<100ms空中数据延时 */
	return cd & 1;
}
int minet_hal_write(minet_if_t *nif, void *buf, int len)
{
	uint8_t reg;
	uint8_t dump;
	int i;
	int n;
	int re;

	n = nif->nbus;
	bk2425_addr(nif->nbus, nif->nid + nif->chl);
	bk2425_cs_clr(n);
//	reg = CMD_WR_TXPLOAD_NOACK;
	reg = CMD_WR_TXPLOAD;
	spi_write(n, &reg, 1);
	len = len > BK2425_PLOAD_SZ ? BK2425_PLOAD_SZ : len;
	spi_write(n, (uint8_t*) buf, len);/* 写数据到TX FIFO,32个字节 */
	if (len < BK2425_PLOAD_SZ)
	{
		re = BK2425_PLOAD_SZ - len;
		for (i = 0; i < re; ++i)
		{
			dump = 0x00;
			spi_write(n, &dump, 1);
		}
	}
	bk2425_cs_set(n);
	bk2425_reg_write(n, CMD_WR_REG + REG_CONFIG, 0x0E);/* EN_CRC=1/2byte,PWR_UP=1,PRIM_RX=0 */
	bk2425_ce_set(n);
	sys_delay(1);

	/* TX_DS: Data Sent TX FIFO interrupt Asserted when packet transmitted on TX.
	 * If AUTO_ACK is activated, this bit is set high only when ACK is received.
	 * Write 1 to clear bit
	 *
	 * MAX_RT: Maximum number of TX retransmits interrupt Write 1 to clear bit.
	 * If MAX_RT is asserted it must be cleared to enable further communication */
	for (i = 0; i < 3; ++i)
	{
		dump = bk2425_reg_read(n, CMD_RD_REG + REG_FIFO_STATUS);/* 读取FIFO状态寄存器的值 */
		dump = bk2425_reg_read(n, CMD_RD_REG + REG_STATUS);/* 读取状态寄存器的值 */
		bk2425_reg_write(n, CMD_WR_REG + REG_STATUS, dump);/* 清除TX_DS或MAX_RT中断标志 */
		if (dump & TX_DS)/* 发送完成 */
		{
			bk2425_reg_write(n, CMD_WR_REG + REG_CONFIG, 0x0F);/* EN_CRC=1/2byte,PWR_UP=1,PRIM_RX=1 */
			sys_delay(3);
			return len;
		}
		if ((dump & MAX_RT) || (dump & 1))/* 达到最大重发次数 || TX_FULL */
		{
			bk2425_buf_write(n, CMD_FLUSH_TX, NULL, 0);/* 清除TX FIFO寄存器 */
			break;
		}
		sys_delay(1);
	}

	bk2425_reg_write(n, CMD_WR_REG + REG_CONFIG, 0x0F);/* EN_CRC=1/2byte,PWR_UP=1,PRIM_RX=1 */
	sys_delay(3);
	return 0;
}
int minet_hal_read(minet_if_t *nif, void *buf, int sz)
{
	uint8_t reg;
	uint8_t dump;
	int i;
	int n;
	int re;

	n = nif->nbus;
	/* RX_DR: Data Ready RX FIFO interrupt Asserted when new data arrives
	 * RX FIFO Write 1 to clear bit.
	 *
	 * FLUSH_RX: Flush RX FIFO, used in RX mode Should not be executed during transmission
	 * of acknowledge, that is, acknowledge package will not be completed. */
	dump = bk2425_reg_read(n, CMD_RD_REG + REG_STATUS);/* 读取状态寄存器的值 */
	bk2425_reg_write(n, CMD_WR_REG + REG_STATUS, dump);/* 清除TX_DS或MAX_RT中断标志 */
	if (dump & RX_DR)/* 接收到数据 */
	{
		bk2425_cs_clr(n);
		reg = CMD_RD_RXPLOAD;
		spi_write(n, &reg, 1);
		sz = sz > BK2425_PLOAD_SZ ? BK2425_PLOAD_SZ : sz;
		spi_read(n, (uint8_t*) buf, sz);
		if (sz < BK2425_PLOAD_SZ)
		{
			re = BK2425_PLOAD_SZ - sz;
			for (i = 0; i < re; ++i)
			{
				dump = 0xff;
				spi_write(n, &dump, 1);
			}
		}
		bk2425_cs_set(n);
		bk2425_buf_write(n, CMD_FLUSH_RX, NULL, 0);/* 清除RX FIFO寄存器 */
		return sz;
	}
	return 0;
}
#elif (MINET_RFSOC==MINET_RFSOC_SI24R1)
#include <string.h>
#include <drv_spi.h>
#include <sys.h>
void minet_hal_wdt_feed(void)
{
	sys_watchdog_feed();
}
uint32_t minet_hal_tick1s(void)
{
	return sys.run;
}
uint32_t minet_hal_random(void)
{
	uint32_t r = sys.tick & 0xFFF;
	return sys.run ^ r;
}

#include <stm32f4xx_ll_gpio.h>
#include <main.h>
//SI24R1 PIN DEFINITION
#define si24r1_cs_clr() LL_GPIO_ResetOutputPin(SPI1_CS_GPIO_Port,SPI1_CS_Pin)/* SPI Chip Select, Active low */
#define si24r1_cs_set() LL_GPIO_SetOutputPin(SPI1_CS_GPIO_Port,SPI1_CS_Pin)/* SPI Chip Select, Active low */
#define si24r1_ce_clr() LL_GPIO_ResetOutputPin(SPI1_CE_GPIO_Port,SPI1_CE_Pin)/* Chip Enable Activates RX or TX mode */
#define si24r1_ce_set() LL_GPIO_SetOutputPin(SPI1_CE_GPIO_Port,SPI1_CE_Pin)/* Chip Enable Activates RX or TX mode */
//#define si24r1_irq() ( 0 )// Interrupt signal
int si24r1_irq(void)// Interrupt signal
{
	return (LL_GPIO_ReadInputPort(SPI1_IRQ_GPIO_Port) & SPI1_IRQ_Pin) ? 1 : 0;
}

int minet_hal_init(minet_if_t *nif)
{
	/* TODO: */
	return -1;
}
int minet_hal_rssi(minet_if_t *nif)
{
	/* TODO: */
	return 0;
}
int minet_hal_chl(minet_if_t *nif, int chl)
{
	nif->chl = chl % MINET_CHL_MAX;
	/* TODO: */
	return 0;
}
int minet_hal_cd(minet_if_t *nif)
{
	/* TODO:除CD功能，添加<100ms空中数据延时 */
	return 0;
}
int minet_hal_write(minet_if_t *nif, void *buf, int len)
{
	/* TODO: */
	return 0;
}
int minet_hal_read(minet_if_t *nif, void *buf, int sz)
{
	/* TODO: */
	return 0;
}

/*----------------------------------------------------------------------------*/
// SPI(SI24R1) commands
#define CMD_RD_REG			( 0x00 )// Define read command to register
#define CMD_WR_REG			( 0x20 )// Define write command to register
#define CMD_RD_RXPLOAD		( 0x61 )// Define RX payload register address
#define CMD_WR_TXPLOAD		( 0xA0 )// Define TX payload register address
#define CMD_FLUSH_TX		( 0xE1 )// Define flush TX register command
#define CMD_FLUSH_RX		( 0xE2 )// Define flush RX register command
#define CMD_REUSE_TX_PL		( 0xE3 )// Define reuse TX payload register command
#define CMD_NOP				( 0xFF )// Define No Operation, might be used to read status register

// SPI(SI24R1) registers(addresses)
#define REG_CONFIG			( 0x00 )// 'Config' register address
#define REG_EN_AA			( 0x01 )// 'Enable Auto Acknowledgment' register address
#define REG_EN_RXADDR		( 0x02 )// 'Enabled RX addresses' register address
#define REG_SETUP_AW		( 0x03 )// 'Setup address width' register address
#define REG_SETUP_RETR		( 0x04 )// 'Setup Auto. Retrans' register address
#define REG_RF_CH			( 0x05 )// 'RF channel' register address
#define REG_RF_SETUP		( 0x06 )// 'RF setup' register address
#define REG_STATUS			( 0x07 )// 'Status' register address
#define REG_OBSERVE_TX		( 0x08 )// 'Observe TX' register address
#define REG_RSSI			( 0x09 )// 'Received Signal Strength Indecator' register address
#define REG_RX_ADDR_P0		( 0x0A )// 'RX address pipe0' register address
#define REG_RX_ADDR_P1		( 0x0B )// 'RX address pipe1' register address
#define REG_RX_ADDR_P2		( 0x0C )// 'RX address pipe2' register address
#define REG_RX_ADDR_P3		( 0x0D )// 'RX address pipe3' register address
#define REG_RX_ADDR_P4		( 0x0E )// 'RX address pipe4' register address
#define REG_RX_ADDR_P5		( 0x0F )// 'RX address pipe5' register address
#define REG_TX_ADDR			( 0x10 )// 'TX address' register address
#define REG_RX_PW_P0		( 0x11 )// 'RX payload width, pipe0' register address
#define REG_RX_PW_P1		( 0x12 )// 'RX payload width, pipe1' register address
#define REG_RX_PW_P2		( 0x13 )// 'RX payload width, pipe2' register address
#define REG_RX_PW_P3		( 0x14 )// 'RX payload width, pipe3' register address
#define REG_RX_PW_P4		( 0x15 )// 'RX payload width, pipe4' register address
#define REG_RX_PW_P5		( 0x16 )// 'RX payload width, pipe5' register address
#define REG_FIFO_STATUS		( 0x17 )// 'FIFO Status Register' register address

// REG_STATUS Register
#define RX_DR			( 0x40 )/*  */
#define TX_DS			( 0x20 )
#define MAX_RT			( 0x10 )

/*----------------------------------------------------------------------------*/
#define SI24R1_ADDR_SZ	( 5 ) // 发送/接收地址
#define SI24R1_PLOAD_SZ ( 32 )// 数据通道有效数据宽度

/*----------------------------------------------------------------------------*/
#else
#error MINET_RFSOC select error
#endif
